import { ScreenSpaceEventHandler, ScreenSpaceEventType, Viewer, Entity, HeightReference, Cartesian3, Color, JulianDate, Cartesian2 } from 'cesium';
import EventDispatcher from '../EventDispatcher/EventDispatcher';
import { MultiEditManager } from '../Edit/MultiEditManager';

export enum GeometryType {
    'COMMON_POINT',
    'COMMON_LABEL',
    'COMMON_BILLBOARD',
    'COMMON_MODEL',
    'COMMON_LINE',
    'COMMON_POLYGON',
    'COMMON_RECTANGLE',
    'COMMON_CIRCLE',
    'COMMON_ELLIPSE',
    'COMMON_ELLIPSE2',
    'COMMON_SECTOR',
    'STRAIGHT_ARROW',
    'STRAIGHT_LINE_ARROW',
    'ATTACK_ARROW',
    'SWALLOWTAIL_ATTACK_ARROW',
    'PINCER_ATTACK_ARROW'
}


export abstract class BaseDraw {
    protected viewer: Viewer;
    protected dispatcher: EventDispatcher;
    protected handler: ScreenSpaceEventHandler;
    protected active = false;          // 是否处于绘制状态
    protected finished = false;        // 是否已结束
    protected tempEntity?: Entity;     // 绘制过程中跟随鼠标的临时实体
    protected pointEntities: Entity[] = []; // 已落点的实体（可用于回退、编辑）

    private clickIndex = 0; /// 点击次数，用于生成控制点的id

    multiEditManager: MultiEditManager;

    protected geometryType: GeometryType;
    protected minPointCount: number; // 最小点击次数

    protected tempCursor?: Cartesian3;

    constructor(viewer: Viewer, dispatcher: EventDispatcher) {
        this.viewer = viewer;
        this.dispatcher = dispatcher;
        this.handler = new ScreenSpaceEventHandler(viewer.canvas);
        this.geometryType = GeometryType.COMMON_POINT;
        this.minPointCount = 1;


        this.multiEditManager = MultiEditManager.getInstance(this.viewer, dispatcher);
    }

    /** 子类必须实现：根据当前点序列生成最终实体 */
    protected abstract buildFinalEntity(): Entity;

    /** 子类可实现：生成跟随鼠标的临时图形 */
    protected abstract buildTempEntity(): Entity | undefined;



    /** 开始绘制 */
    start() {
        if (this.active || this.finished) return;
        this.active = true;
        this.finished = false;

        // 左键落点
        this.handler.setInputAction((e: any) => this.onLeftClick(e), ScreenSpaceEventType.LEFT_CLICK);
        // 鼠标移动
        this.handler.setInputAction((e: any) => this.onMouseMove(e), ScreenSpaceEventType.MOUSE_MOVE);
        // 右键结束
        this.handler.setInputAction(() => this.finish(), ScreenSpaceEventType.RIGHT_CLICK);

        this.dispatcher.dispatchEvent('DRAWSTART', { type: this.constructor.name, text: "开始绘制" });
    }

    protected onLeftClick(e: any) {
        const cartesian = this.safePick(e.position || e.endPosition);
        if (!cartesian) return;

        this.clickIndex++;

        this.addPoint(cartesian);
        this.dispatcher.dispatchEvent('DRAWUPDATE', { type: this.constructor.name, points: this.getPositions() });
    }

    protected onMouseMove(e: any) {

        const cartesian = this.safePick(e.position || e.endPosition);

        if (!cartesian) return;

        this.updateTempEntity(cartesian);
        // 更新临时图形
        if (!this.tempEntity) {
            this.tempEntity = this.buildTempEntity();
        }


        this.dispatcher.dispatchEvent('MOUSEMOVE', { type: this.constructor.name, points: this.getPositions(), cursor: cartesian, text: "添加下一个点，右键可结束绘制。" });
    }

    protected addPoint(position: Cartesian3) {
        // 落点显示
        const point = this.viewer.entities.add({
            id: "control_point_entity_" + this.clickIndex,
            position,
            point: {
                pixelSize: 10,
                color: Color.YELLOW,
                heightReference: HeightReference.CLAMP_TO_GROUND,
                disableDepthTestDistance: Number.POSITIVE_INFINITY  // 始终不被地形遮挡 
            }
        });
        this.pointEntities.push(point);
    }
    /** 安全地拾取贴地点；失败返回 undefined */
    private safePick(windowPos: Cartesian2): Cartesian3 | undefined {
        const ray = this.viewer.camera.getPickRay(windowPos);
        if (!ray) return undefined;
        return this.viewer.scene.globe.pick(ray, this.viewer.scene)
            ?? this.viewer.scene.globe.ellipsoid.scaleToGeodeticSurface(ray.origin);
    }



    /** 当前可用于成面的点数 */
    // protected get validPositions(): Cartesian3[] {
    //     const pts = this.getPositions();
    //     return pts.length >= 1 ? pts : [];
    // }


    /** 结束绘制 */
    finish() {
        if (!this.active) return;
        this.active = false;
        this.finished = true;
        this.handler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
        this.handler.removeInputAction(ScreenSpaceEventType.MOUSE_MOVE);
        this.handler.removeInputAction(ScreenSpaceEventType.RIGHT_CLICK);

        // 移除临时
        if (this.tempEntity) {
            this.viewer.entities.remove(this.tempEntity);
            this.tempEntity = undefined;
        }
        //移除pointEntities中所有id包含control_point_entity_的点
        this.pointEntities.forEach(p => {
            if (p.id.includes("control_point_entity_")) {
                this.viewer.entities.remove(p);
            }
        });

        if (this.clickIndex < this.minPointCount) {
            this.dispatcher.dispatchEvent('DRAWEND', { type: this.constructor.name, points: this.getPositions(), text: "点击次数不足，请重新绘制" });
            return;
        } else {
            const final = this.buildFinalEntity();
            this.dispatcher.dispatchEvent('DRAWEND', { type: this.constructor.name, entity: final, points: this.getPositions(), text: "绘制完成" });
            // 登记到多编辑管理器
            this.multiEditManager.register(final, this.getPositions(), this.geometryType);
        }

        this.clickIndex = 0
    }

    /** 清理 */
    destroy() {
        this.finish();
        this.pointEntities.forEach(p => this.viewer.entities.remove(p));
        this.pointEntities = [];
        this.handler.destroy();
    }
    
    /** 子类可重写：返回当前已有点序列 */
    protected getPositions(): Cartesian3[] {
        return this.pointEntities.map(e => e.position!.getValue(JulianDate.now())!);
    }

    /** 更新临时图形（子类可重写） */
    protected updateTempEntity(cursor: Cartesian3) {
        // 默认空实现
        this.tempCursor = cursor;
    }
}